'use strict';
// Copyright 2014 Blueant Inc. All Rights Reserved.

/**
 * @fileoverview 登陆服务器
 * @author sundbcn@gmail.com (sun debing)
 */

var moment = require('moment');
var pomelo = require('pomelo');
var async = require('async');
var _ = require('lodash');
var Code = require('../../../consts/code');
var PlayerManager = require('../../../libs/playerManager');
var roleModel = require('../../../models/roleModel');
var userModel = require('../../../models/userModel');
var serverStatusModel = require('../../../models/serverStatusModel.js');
var channelUtil = require('../../../util/channelUtil');
var battleService = require('../../../services/battleService');
var authService = require('../../../services/authService');
var analyze = require('../../../libs/analyze');
var fightPowerService = require('../../../services/fightPowerService');
var activityService = require('../../../services/activityService');
var onlineUserCountService = require('../../../services/onlineUserCountService.js');
var actType = require('../../../consts/activityType.js');
var unionGroupModel = require('../../../models/unionGroupModel.js');
var taskSynchronizationService = require('../../../services/taskSynchronizationService.js');
var unionHelpModel = require('../../../models/unionHelpModel.js');
var haveHelpModel = require('../../../models/haveHelpModel.js');
var unionGroupMgr = require('../../../mgr/unionGroupMgr.js');
var haveHelpMgr = require('../../../mgr/haveHelpMgr.js');
var moduleType = require('../../../consts/moduleType.js');
var operationType = require('../../../consts/operationType');

module.exports = function (app) {
    return new Handler(app);
};

var Handler = function (app) {
    this.app = app;
    this.globalChannelService = app.get('globalChannelService');
};

/**
 * 新用户登陆
 */
Handler.prototype.entry = function (msg, session, next) {
    var self = this;
    var signed_key = msg.signed_key;
    var job_type = msg.job_type;

    if (!signed_key || !job_type) {
        return next(null, {
            code: Code.PARAM_ERROR
        });
    }

    var role_id;
    var auth_uid;
    var channel_id;
    var sessionService;
    var battle_record;
    var player_manager;
    var union_id = 0;
    var union_group_model;
    var create_time;
    var only_id_list = [];
    var help_list = [];
    var have_info = [];
    var union_help_msg = {};
    var role_model;

    async.waterfall(
        [
            function (cb) {
                serverStatusModel.isGameLocked(cb);
            },
            function (game_locked, cb) {
                console.log('------ game_locked:', game_locked);
                if (game_locked) {
                    // 服务器已锁定(停服维护)
                    return next(null, {
                        code: Code.ENTRY_SERVER_LOCKED
                    });
                }

                // 与账号服务器验证signed_key
                authService.checkSignedKey(signed_key, cb);
            },
            function (uid, chn, cb) {
                auth_uid = uid;
                _getForbidStatus(auth_uid, cb);
            },
            function (forbid_status, cb) {
                if (!!forbid_status) {
                    return next(null, {
                        code: Code.ENTRY_HAVE_FORBID
                    });
                }

                session.set('auth_uid', auth_uid);
                roleModel.getByJob(auth_uid, job_type, cb);
            },
            function (model, cb) {
                if (!model) {
                    return next(null, {
                        code: Code.ENTRY_CAN_NOT_PASS
                    });
                }
                role_id = model.getRoleId();
                union_id = model.union_id;
                channel_id = model.channel_id;
                create_time = model.create_time;

                sessionService = pomelo.app.get('sessionService');
                var old_session = sessionService.getByUid(role_id);
                if (!old_session) {
                    return cb();
                }
                if (old_session[0].id !== session.id) {
                    sessionService.kickBySessionId(old_session[0].id, 'kick_old_session', cb);
                    return;
                }
                cb();
            },
            function (cb) {
                session.bind(role_id, cb);
                session.set('channel_id', channel_id);
            },
            function (cb) {
                session.on('closed', onUserLeave.bind(self, self.app));
                session.pushAll(cb);
            },
            function (cb) {
                onlineUserCountService.addOnlineUser(channel_id, cb);
            },
            function (cb) {
                player_manager = new PlayerManager(role_id);
                player_manager.getAllModel(cb);
            },
            function (cb) {
                player_manager.refreshData(cb);
            },
            function (cb) {
                self.globalChannelService.add(channelUtil.getGlobalChannelName(), role_id, self.app.get('serverId'), cb);
            },
            function (cb) {
                taskSynchronizationService.synchronization(player_manager, cb);
            },
            function (cb) {
                if (!!union_id) {
                    self.globalChannelService.add(union_id, role_id, self.app.get('serverId'), cb);
                } else {
                    cb();
                }
            },
            function (cb) {
                var activity_model = player_manager.activity;
                role_model = player_manager.role;

                // 计算累计登陆天数
                if (moment(role_model.getLastLoginTime()) < moment().startOf('day')) {
                    activity_model.addContinuouslyLoginDays();
                }

                if (role_model.hero_power === 0) {
                    fightPowerService.initFightPower(player_manager);
                }

                cb();
            },
            function (cb) {
                roleModel.login(role_id, cb);
            },
            function (cb) {
                battleService.getRecordList(role_id, cb);
            },
            function (record, cb) {
                battle_record = record;
                cb();
            },
            function (cb) {
                haveHelpModel.findUnionHelpList(role_id, function (err, have_list_all) {
                    have_info = have_list_all;
                    cb();
                });
            },
            function (cb) {
                if (!!union_id) {
                    unionGroupModel.getById(union_id, function (err, union_model) {
                        if (!!err) {
                            console.error('err------------union mgr not ', err);
                        }
                        union_group_model = union_model;
                        cb();
                    });
                } else {
                    cb();
                }
            },
            function (cb) {
                if (!!union_id) {
                    unionHelpModel.findUnionHelpList(union_id, function (err, help_list1) {
                        _.each(help_list1, function (item_old) {
                            if (item_old.help_max_num >= 1) {
                                help_list.push(item_old);
                            }
                        });
                        cb();
                    });
                } else {
                    cb();
                }
            },

            function (cb) {
                if (!!union_id) {
                    union_help_msg = {
                        is_modify: 1,
                        help_list: help_list
                    };
                    cb();
                } else {
                    cb();
                }
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
                return next(null, {
                    code: Code.FAIL
                });
            }
            _analyzeLogin(role_id, channel_id, create_time);
            player_manager.save();
            player_manager.push();
            activityService.push(role_id, actType.ALL, player_manager);
            if (!!union_group_model) {
                union_group_model.pushModifyToRole(role_id);
                haveHelpMgr.sendHaveHelpChanged(
                    role_id, {
                        have_list: have_info,
                        is_modify: 1
                    },
                    function (err, fails) {
                        if (err) {
                            return;
                        }
                    }
                );
                unionGroupMgr.sendUnionHelpChangedOnly(
                    role_id,
                    union_help_msg,
                    function (err, fails) {
                        if (err) {
                            return;
                        }
                    }
                );
            }
            return next(null, {
                code: Code.OK,
                result: {
                    player: {
                        build: player_manager.build.toJSON()
                    },
                    current_time: moment().unix(),
                    battle_record: battle_record,
                    guide: player_manager.guide.getProgress()
                }
            });
        }
    );
};

var onUserLeave = function (app, session) {
    if (!session || !session.uid) {
        return;
    }

    roleModel.logout(session.uid, function (err) {
        if (err) {
            console.error('role %s logout failed, error %j: ', session.uid, err);

        }
    });

    this.globalChannelService.leave(channelUtil.getGlobalChannelName(), session.uid, app.get('serverId'), function (err) {
        if (err) {
            console.error('role %s leave failed, error %j: ', session.uid, err);

        }
    });

    var channel_id = session.get('channel_id');
    roleModel.getByRoleId(session.uid, function (err, role_model) {
        if (!!role_model) {
            var last_login_time = moment(role_model.getLastLoginTime()).unix();
            var now_time = moment().unix();
            var diff = Math.ceil((now_time - last_login_time) / 60);
            _analyzeOnlineTime(session.uid, channel_id, diff);
        }

        onlineUserCountService.subOnlineUser(channel_id);
    });
};

/**
 * 获取封停状态
 */
var _getForbidStatus = function (auth_uid, cb) {
    userModel.getByUid(auth_uid, function (err, model) {
        if (!!err) {
            return cb(err);
        }
        cb(null, model.isForbid());
    });
};

/**
 * 统计登录
 * @param  {[type]} role_id [description]
 * @return {[type]}         [description]
 */
var _analyzeLogin = function (role_id, channel_id, create_time) {
    analyze.recordLogin(role_id, channel_id, create_time);
};

/**
 * 统计在线时间
 * @param  {[type]} role_id [description]
 * @return {[type]}         [description]
 */
var _analyzeOnlineTime = function (role_id, channel_id, time) {
    analyze.recordOnlineTime(role_id, channel_id, time);
};
